#include "CpuZ80.h"
#include <memory>
#include <cstring>

void CpuZ80::PrepareTables()
{
	for (size_t i = 0; i <= 0xFF; ++i)
	{
		size_t count = 0;

		for (size_t j = 0; j < 8; ++j)
			if (((i >> j) & 1) > 0) ++count;

		m_parityTable[i] = (count % 2 == 0);
	}


	byte_t cycles [256] = 
	{// 0	1		2		3		4		5		6		7		8		9	  A	    B	    C 	    D	    E	F
		4,	10,		7,		6,		4,		4,		7,		4,		4,		11,   7,	6,		4,		4,		7,	4,		// 0x00
		8,	10,		7,		6,		4,		4,		7,		4,		12,		11,   7,	6,		4,		4,		7,	4,		// 0x10
		7,	10,		16,		6,		4,		4,		7,		4,		7,		11,  16,	6,		4,		4,		7,	4,		// 0x20
		7,	10,		13,		6,		11,	   11,		10,		4,		7,		11,  13,	6,		4,		4,		7,	4,		// 0x30
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x40
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x50
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x60
		7,	7,		7,		7,		7,		7,		4,		7,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x70
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x80
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0x90
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0xA0
		4,	4,		4,		4,		4,		4,		7,		4,		4,		4,    4,	4,		4,		4,		7,	4,		// 0xB0
		5,	10,		10,		10,	   10,     11,		7,		11,		5,		10,  10,	0,		10,		17,		7,	11,		// 0xC0
		5,	10,		10,		11,	   10,	   11,		7,		11,		5,		4,   10,	11,		10,		0,		7,	11,		// 0xD0
		5,	10,		10,		18,	   11,	   11,		7,		11,		5,		5,   10,	5,		11,		0,		7,	11,		// 0xE0
		5,	10,		10,		4,	   11,	   11,		7,		11,		5,		5,   10,	4,		11,		0,		7,	11		// 0xF0
	};

	memcpy(m_cycles, cycles, 256);


	byte_t cyclesCB [256] =
	{// 0	1		2		3		4		5		6		7		8		9	  A	    B	    C 	    D	    E	F
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x00
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x10
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x20
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x30
		8,	8,		8,		8,		8,		8,		12,		8,		8,	    8,    8,	8,		8,		8,		12,	8,		// 0x40
		8,	8,		8,		8,		8,		8,		12,		8,		8,	    8,    8,	8,		8,		8,		12,	8,		// 0x50
		8,	8,		8,		8,		8,		8,		12,		8,		8,	    8,    8,	8,		8,		8,		12,	8,		// 0x60
		8,	8,		8,		8,		8,		8,		12,		8,		8,	    8,    8,	8,		8,		8,		12,	8,		// 0x70
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x80
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0x90
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0xA0
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0xB0
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0xC0
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0xD0
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8,		// 0xE0
		8,	8,		8,		8,		8,		8,		15,		8,		8,	    8,    8,	8,		8,		8,		15,	8		// 0xF0
	};

	memcpy(m_cyclesCB, cyclesCB, 256);

	byte_t cyclesED [256] =
	{// 0	    1		2		3		4		5		6		7		8		9	   A	    B	    C 	    D	    E		F
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x00
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x10
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x20
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x30
		12,	    12,		15,		20,		8,		10,		8,		9,		12,	    12,    15,		20,		0,		10,		0,		9,		// 0x40
		12,	    12,		15,		20,		0,		0,		8,		9,		12,	    12,    15,		20,		0,		0,		8,		4,		// 0x50
		12,	    12,		15,		16,		0,		0,		0,		0,		12,	    12,    15,		16,		0,		0,		0,		0,		// 0x60
		0,	    0,		15,		20,		0,		0,		0,		0,		12,	    12,    15,		20,		0,		0,		0,		0,		// 0x70
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x80
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0x90
		16,	    16,		16,		16,		0,		0,		0,		0,		16,	    16,    16,		16,		0,		0,		0,		0,		// 0xA0
		16,	    16,		16,		16,		0,		0,		0,		0,		16,	    16,    16,		16,		0,		0,		0,		0,		// 0xB0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0xC0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0xD0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0,		// 0xE0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,	    0,     0,		0,		0,		0,		0,		0		// 0xF0
	};

	memcpy(m_cyclesED, cyclesED, 256);

	byte_t cyclesDD [256] =
	{// 0	    1		2		3		4		5		6		7		8		9	   A	    B	    C 	    D	    E		F
		0,	    0,		0,		0,		0,		0,		0,		0,		0,		15,		0,		0,		0,		0,		0,		0,		// 0x00
		0,	    0,		0,		0,		0,		0,		0,		0,		0,		15,		0,		0,		0,		0,		0,		0,		// 0x10
		0,	    14,		0,		10,		4,		4,		0,		0,		0,		15,		20,		10,		4,		4,		0,		0,		// 0x20
		0,	    0,		0,		0,		23,		23,		19,		0,		0,		15,		0,		0,		0,		0,		0,		0,		// 0x30
		4,	    4,		4,		4,		4,		4,		19,		4,		4,		4,		4,		4,		4,		4,		19,		4,		// 0x40
		4,	    4,		4,		4,		4,		4,		19,		4,		4,		4,		4,		4,		4,		4,		19,		4,		// 0x50
		4,	    4,		4,		4,		4,		4,		19,		4,		4,		4,		4,		4,		4,		4,		19,		4,		// 0x60
		19,	    19,		19,		19,		19,		19,		0,		19,		4,		4,		4,		4,		4,		4,		19,		4,		// 0x70
		0,	    0,		0,		0,		8,		8,		19,		0,		0,		0,		0,		0,		8,		8,		19,		0,		// 0x80
		0,	    0,		0,		0,		8,		8,		19,		0,		0,		0,		0,		0,		8,		8,		19,		0,		// 0x90
		0,	    0,		0,		0,		8,		8,		19,		0,		0,		0,		0,		0,		8,		8,		19,		0,		// 0xA0
		0,	    0,		0,		0,		8,		8,		19,		0,		0,		0,		0,		0,		8,		8,		19,		0,		// 0xB0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		// 0xC0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		0,		// 0xD0
		0,	    14,		0,		25,		0,		14,		0,		0,		0,		8,		0,		0,		0,		0,		0,		0,		// 0xE0
		0,	    0,		0,		0,		0,		0,		0,		0,		0,		10,		0,		0,		0,		0,		0,		0		// 0xF0
	};

	memcpy(m_cyclesDD, cyclesDD, 256);
	memcpy(m_cyclesFD, cyclesDD, 256);

	byte_t cyclesDDCB [256] =
	{// 0	    1		2		3		4		5		6		7		8		9	   A	    B	    C 	    D	    E		F
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0x00
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0x10
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0x20
		0,	    0,		0,		0,		0,		0,		20,		0,		0,	    0,     0,		0,		0,		0,		20,		0,		// 0x30
		0,	    0,		0,		0,		0,		0,		20,		0,		0,	    0,     0,		0,		0,		0,		20,		0,		// 0x40
		0,	    0,		0,		0,		0,		0,		20,		0,		0,	    0,     0,		0,		0,		0,		20,		0,		// 0x50
		0,	    0,		0,		0,		0,		0,		20,		0,		0,	    0,     0,		0,		0,		0,		20,		0,		// 0x60
		0,	    0,		0,		0,		0,		0,		20,		0,		0,	    0,     0,		0,		0,		0,		20,		0,		// 0x70
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0x80
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0x90
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0xA0
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0xB0
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0xC0
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0xD0
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0,		// 0xE0
		0,	    0,		0,		0,		0,		0,		23,		0,		0,	    0,     0,		0,		0,		0,		23,		0		// 0xF0
	};

	memcpy(m_cyclesDDCB, cyclesDDCB, 256);
	memcpy(m_cyclesFDCB, cyclesDDCB, 256);
}
